home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / PlThink.c < prev    next >
C/C++ Source or Header  |  1994-09-28  |  13KB  |  529 lines

  1. #include "wolfdef.h"
  2.  
  3. #define SHOTRATE 6
  4.  
  5. /**********************************
  6.  
  7.     Change my weapon to the biggest one I got
  8.             
  9. **********************************/
  10.  
  11. static void OutOfAmmo(void)
  12. {      
  13.     if (gamestate.missile && gamestate.missiles) {
  14.         gamestate.pendingweapon = WP_MISSILE;
  15.         return;        /* Launcher & missiles */
  16.     }
  17.     if (gamestate.flamethrower && gamestate.gas) {
  18.         gamestate.pendingweapon = WP_FLAMETHROWER;
  19.         return;        /* Flames and gas */
  20.     }
  21.     if (gamestate.ammo) {
  22.         if (gamestate.chaingun) {
  23.             gamestate.pendingweapon = WP_CHAINGUN;
  24.             return;
  25.         }
  26.         if (gamestate.machinegun) {
  27.             gamestate.pendingweapon = WP_MACHINEGUN;
  28.             return;
  29.         }
  30.         gamestate.pendingweapon = WP_PISTOL;
  31.         return;
  32.     }
  33.     gamestate.pendingweapon = WP_KNIFE;
  34. }
  35.  
  36.         
  37. /**********************************
  38.  
  39.     Draw the ammo for the new weapon
  40.             
  41. **********************************/
  42.  
  43. void ChangeWeapon (void)
  44. {
  45.     switch(gamestate.weapon) {    /* Which weapon */
  46.     case WP_PISTOL:
  47.     case WP_MACHINEGUN:
  48.     case WP_CHAINGUN:
  49.         IO_DrawAmmo(gamestate.ammo);    /* Draw bullets */
  50.         break;
  51.     case WP_FLAMETHROWER:
  52.         IO_DrawAmmo(gamestate.gas);        /* Draw gasoline */
  53.         break;
  54.     case WP_MISSILE:
  55.         IO_DrawAmmo(gamestate.missiles);    /* Draw missiles */
  56.     }        
  57. }
  58.  
  59. /**********************************
  60.  
  61.     Fire my weapon, change to knife if no more ammo
  62.             
  63. **********************************/
  64.  
  65. void Cmd_Fire(void)
  66. {
  67.     switch(gamestate.weapon) {
  68.     case WP_CHAINGUN:
  69.     case WP_MACHINEGUN:
  70.     case WP_PISTOL:
  71.         if (!gamestate.ammo) {    /* Do I have ammo? */
  72.             OutOfAmmo();    /* Change the weapon */
  73.         }
  74.         break;
  75.     case WP_FLAMETHROWER:
  76.         if (!gamestate.gas) {
  77.             OutOfAmmo();    /* Change the weapon */
  78.         }
  79.         break;
  80.     case WP_MISSILE:
  81.         if (!gamestate.missiles) {
  82.             OutOfAmmo();    /* Change the weapon */
  83.         }
  84.     }
  85.     gamestate.attackframe = 1;        /* Begin the attack */
  86.     gamestate.attackcount = SHOTRATE;        /* Time before next action */
  87. }
  88.  
  89. /**********************************
  90.  
  91.     Try to use a switch, door or pushwall...
  92.             
  93. **********************************/
  94.  
  95. void Cmd_Use(void)
  96. {
  97.     Word dir;        /* Direction facing */
  98.     Word tile;        /* Tile tested */
  99.     Word x,y;        /* x,y of the tile to test */
  100.  
  101. /* Find which cardinal direction the player is facing */
  102.  
  103.     x = actors[0].x >> FRACBITS;    /* Get the x,y in tiles */
  104.     y = actors[0].y >> FRACBITS;
  105.     
  106.     dir = ((gamestate.viewangle+ANGLES/8)&(ANGLES-1)) >> 7;    /* Force into a cardinal direction */
  107.  
  108.     switch (dir) {
  109.     case 0:
  110.         x++;
  111.         dir = CD_EAST;    /* East */
  112.         break;
  113.     case 1:
  114.         y--;
  115.         dir = CD_NORTH;    /* North */
  116.         break;
  117.     case 2:
  118.         x--;
  119.         dir = CD_WEST;    /* West */
  120.         break;
  121.     case 3:
  122.         y++;
  123.         dir = CD_SOUTH;    /* South */
  124.     }
  125.  
  126.     tile = tilemap[y][x];        /* Get the tile data */    
  127.     if (tile & TI_DOOR) {        /* Is this a door? */
  128.         OperateDoor(tile&TI_NUMMASK);    /* Door # to operate */
  129.         return;
  130.     }
  131.  
  132.     if (!PushWallRec.pwallcount && (tile&TI_PUSHWALL)) {    /* Push wall? */
  133.         PushWall(x,y,dir);            /* Note: Only 1 pushwall at a time! */
  134.         return;
  135.     }
  136.  
  137.     if (tile & TI_SWITCH) {        /* Elevator switch? */
  138.         PlaySound(SND_THROWSWITCH|0x8000);
  139.         playstate = EX_COMPLETED;
  140.         return;
  141.     }
  142.     if (tile & TI_SECRET) {        /* Secret level? */
  143.         PlaySound(SND_THROWSWITCH|0x8000);
  144.         playstate = EX_SECRET;
  145.         return;
  146.     }
  147.     if (tile & TI_BLOCKSIGHT) {
  148.         PlaySound(SND_HITWALL|0x8000);        /* Oof! */
  149.     }
  150. }
  151.  
  152. /**********************************
  153.  
  154.     Change my weapon
  155.             
  156. **********************************/
  157.  
  158. void Cmd_ChangeWeapon(void)
  159. {                                                                                                                                                                                                                                                                                                                                                                                       
  160.     for (;;) {
  161.         ++gamestate.pendingweapon;        /* Next weapon */
  162.         switch(gamestate.pendingweapon) {
  163.         case WP_PISTOL:
  164.             if (gamestate.ammo)    {    /* Do I have ammo ? */
  165.                 return;        /* Use it! */
  166.             }
  167.             break;            
  168.         case WP_MACHINEGUN:
  169.             if (gamestate.machinegun && gamestate.ammo) {
  170.                 return;        /* Machine gun & ammo! */
  171.             }
  172.             break;
  173.         case WP_CHAINGUN:
  174.             if (gamestate.chaingun && gamestate.ammo) {
  175.                 return;            /* Chain gun & ammo! */
  176.             }
  177.             break;
  178.         case WP_FLAMETHROWER:
  179.             if (gamestate.flamethrower && gamestate.gas) {
  180.                 return;        /* Flames and gas */
  181.             }
  182.             break;
  183.         case WP_MISSILE:
  184.             if (gamestate.missile && gamestate.missiles) {
  185.                 return;        /* Launcher & missiles */
  186.             }
  187.             break;
  188.         default:
  189.             gamestate.pendingweapon = WP_KNIFE;    /* Force as the knife */
  190.             return;
  191.         }        
  192.     }
  193. }
  194.  
  195. /**********************************
  196.  
  197.     Sets actor to the closest enemy in the line of fire, or 0
  198.     if there is no valid target
  199.             
  200. **********************************/
  201.  
  202. actor_t *TargetEnemy (void)
  203. {
  204.     Word *xe;
  205.     Word i;
  206.     vissprite_t    *dseg;
  207.     actor_t *ActorPtr;
  208.  
  209. /* look at the drawn sprites from closest to farthest*/
  210.  
  211.     i = numvisspr;
  212.     if (i) {        /* Any drawn? */
  213.         xe = &firstevent[i-1];        /* Index to the CLOSEST sprite */
  214.         do {
  215.             dseg = &vissprites[xe[0]&(MAXVISSPRITES-1)];
  216.             if (dseg->actornum) {    /* static sprite or missile */
  217.                 if (xscale[CENTERX] <= dseg->clipscale) {    /* Not obscured by a wall*/
  218.                     if (dseg->x1 <= CENTERX+8 && dseg->x2 >= CENTERX-8) {
  219.                         ActorPtr = &actors[dseg->actornum];        /* Get pointer to the actor */
  220.                         if (!(ActorPtr->flags & FL_DEAD)) {        /* Dead already? */
  221.                             return ActorPtr;            /* Shoot me! */
  222.                         }
  223.                     }
  224.                 }
  225.             } 
  226.             --xe;
  227.         } while (--i);
  228.     }
  229.     return 0;        /* No actor in range */
  230. }
  231.  
  232. /**********************************
  233.  
  234.     Attack with a knife
  235.             
  236. **********************************/
  237.  
  238. void KnifeAttack(void)
  239. {
  240.     actor_t *ActorPtr;
  241.     
  242.     ActorPtr = TargetEnemy();    /* Who to hit? */
  243.     if (ActorPtr) {                /* Got someone? */
  244.         if (CalcDistance(ActorPtr) <= KNIFEDIST) {    /* In range? */
  245.             DamageActor(w_rnd()&15,ActorPtr);    /* Hit him! */
  246.             PlaySound(SND_KNIFE|0x8000);
  247.             return;
  248.         }
  249.     }
  250.     PlaySound(SND_KNIFEMISS|0x8000);    /* Swish the knife */
  251. }
  252.  
  253. /**********************************
  254.  
  255.     Attack with a pistol, machine gun, chain gun
  256.             
  257. **********************************/
  258.  
  259. void GunAttack(void)
  260. {
  261.     Word Damage;
  262.     actor_t *ActorPtr;
  263.     
  264.     if (gamestate.weapon == WP_CHAINGUN ) {
  265.         Damage = SND_CHAIN|0x8000;        /* Bang! */
  266.     } else if (gamestate.weapon == WP_MACHINEGUN) {
  267.         Damage = SND_MGUN|0x8000;
  268.     } else {
  269.         Damage = SND_GUNSHT|0x8000;
  270.     }
  271.     PlaySound(Damage);            /* Play the gun shot sound */
  272.     madenoise = TRUE;            /* I made some noise */
  273.     if (!gamestate.godmode) {
  274.         --gamestate.ammo;            /* Remove a bullet */
  275.     }
  276.     IO_DrawAmmo(gamestate.ammo);    /* Redraw the ammo */
  277.  
  278.     ActorPtr = TargetEnemy();    /* Anyone to hit? */
  279.     if (ActorPtr) {                /* Found one? */
  280.         if (CalcDistance(ActorPtr) < 2*TILEGLOBAL) {    /* Close range? */
  281.             Damage = w_rnd()&15;        /* More damage */
  282.         } else {
  283.             Damage = w_rnd()&7;
  284.         }
  285.         DamageActor(Damage,ActorPtr);    /* Shoot! */
  286.     }
  287. }
  288.  
  289. /**********************************
  290.  
  291.     Attack with a flame thrower
  292.             
  293. **********************************/
  294.  
  295. void FlameAttack(void)
  296. {
  297.     int    x;        /* Sine,cos value */
  298.     missile_t *MissilePtr;    /* Pointer to new missile record */
  299.     
  300.     madenoise = TRUE;
  301.     PlaySound(SND_FTHROW|0x8000);    /* Burn! */
  302.     if (!gamestate.godmode) {
  303.         --gamestate.gas;        /* Use a gallon of gas */
  304.     }
  305.     IO_DrawAmmo(gamestate.gas);    /* Draw the gas value */
  306.     
  307. /* flame sprite*/
  308.  
  309.     MissilePtr = GetNewMissile();    /* Get a missile record */
  310.     MissilePtr->areanumber = actors[0].areanumber;    /* Start where I am */
  311.     x = costable[gamestate.viewangle];    /* Set the x velocity */
  312.     MissilePtr->xspeed = x/5;    /* Set the speed */
  313.     MissilePtr->x = (x/4) + actors[0].x;
  314.     x = -sintable[gamestate.viewangle];    /* Set the y velocity */
  315.     MissilePtr->yspeed = x/5;    /* Set the speed */
  316.     MissilePtr->y = (x/4) + actors[0].y;
  317.     MissilePtr->pic = S_FIREBALL;    /* Use the fireball pic */
  318.     MissilePtr->flags = MF_HITENEMIES | MF_HITSTATICS;
  319.     MissilePtr->type = MI_PFLAME;
  320. }
  321.  
  322. /**********************************
  323.  
  324.     Attack with a missile
  325.             
  326. **********************************/
  327.  
  328. void MissileAttack(void)
  329. {
  330.     int    x;        /* Sine,Cos value */    
  331.     missile_t *MissilePtr;    /* Pointer to new missile record */
  332.     
  333.     PlaySound(SND_ROCKET|0x8000);    /* Fire! */
  334.     madenoise = TRUE;        /* Made a racket */
  335.     if (!gamestate.godmode) {
  336.         --gamestate.missiles;
  337.     }
  338.     IO_DrawAmmo(gamestate.missiles);    /* Draw the missile count */
  339.     MissilePtr = GetNewMissile();    /* missile sprite */
  340.     MissilePtr->areanumber = actors[0].areanumber;
  341.     x = costable[gamestate.viewangle];
  342.     MissilePtr->x = (x/4) + actors[0].x;    /* Must be visible for screen! */
  343.     MissilePtr->xspeed = (x/5);
  344.     x = -sintable[gamestate.viewangle];
  345.     MissilePtr->y = (x/4) + actors[0].y;
  346.     MissilePtr->yspeed = (x/5);
  347.     MissilePtr->pic = S_MISSILE;
  348.     MissilePtr->flags = MF_HITENEMIES | MF_HITSTATICS;
  349.     MissilePtr->type = MI_PMISSILE;
  350. }
  351.  
  352. /**********************************
  353.  
  354.     Move the player (Called every tic)
  355.             
  356. **********************************/
  357.  
  358. void MovePlayer(void)
  359. {
  360.     ControlMovement();        /* Read the controller */
  361.  
  362. /* check for use*/
  363.  
  364.     if (buttonstate[bt_use]) {    /* Pressed use? */
  365.         if (!useheld) {
  366.             useheld = TRUE;        /* Only once... */
  367.             Cmd_Use();
  368.         }
  369.     } else {
  370.         useheld = FALSE;    /* It's released */
  371.     }
  372.  
  373. /* check for weapon select */
  374.  
  375.     if (buttonstate[bt_select]) {
  376.         if (!selectheld) {
  377.             selectheld = TRUE;    /* Only once */
  378.             Cmd_ChangeWeapon();    /* Change the weapon */
  379.         }
  380.     } else {
  381.         selectheld = FALSE;        /* It's released */
  382.     }
  383.  
  384. /* check for starting an attack */
  385.  
  386.     if (buttonstate[bt_attack]) {
  387.         if (!attackheld && !gamestate.attackframe) {
  388.             attackheld = TRUE;    /* Held down */
  389.             Cmd_Fire();    /* Initiate firing my weapon */
  390.         }
  391.     } else {
  392.         attackheld = FALSE;    /* It's released */
  393.     }
  394.         
  395. /* advance attacking action */
  396.  
  397.     if (!gamestate.attackframe) {    /* Not in the middle of firing the weapon? */
  398.         if (gamestate.pendingweapon != gamestate.weapon) {    /* New weapon? */
  399.             gamestate.weapon = gamestate.pendingweapon;    /* Set the weapon */
  400.             ChangeWeapon();        /* Redraw the ammo */
  401.         }
  402.         return;    /* Exit now */
  403.     }
  404.     
  405. /* I am in an attack, time yet? */
  406.  
  407.     if (gamestate.attackcount>TicCount) {    /* Wait to attack! */
  408.         gamestate.attackcount-=TicCount;    /* Wait a bit */
  409.         return;
  410.     }
  411.  
  412. /* change frame */
  413.  
  414.     if (TicCount<SHOTRATE) {
  415.         gamestate.attackcount += (SHOTRATE-TicCount);        /* Carry over the time */
  416.     }
  417.     ++gamestate.attackframe;        /* Next animation frame */
  418.  
  419. /* frame 2: attack frame */
  420.  
  421.     if (gamestate.attackframe == 2) {
  422.         switch (gamestate.weapon) {
  423.         case WP_KNIFE:
  424.             KnifeAttack();        /* Knife 'em */
  425.             break;
  426.         case WP_PISTOL:
  427.             if (!gamestate.ammo) {
  428.                 gamestate.attackframe = 4;
  429.                 return;
  430.             }
  431.             GunAttack();        /* One shot */
  432.             break;
  433.         case WP_MACHINEGUN:
  434.             if (!gamestate.ammo) {
  435.                 gamestate.attackframe = 4;
  436.                 return;
  437.             }
  438.             GunAttack();        /* First shot */
  439.             break;
  440.         case WP_CHAINGUN:
  441.             if (!gamestate.ammo) {
  442.                 gamestate.attackframe = 4;
  443.                 return;
  444.             }
  445.             GunAttack();        /* First of many shots */
  446.             break;
  447.         case WP_FLAMETHROWER:
  448.             if (!gamestate.gas) {
  449.                 gamestate.attackframe = 4;
  450.                 return;
  451.             }
  452.             FlameAttack();    /* Shoot a flame */
  453.             break;
  454.         case WP_MISSILE:
  455.             if (!gamestate.missiles) {
  456.                 gamestate.attackframe = 4;
  457.                 return;
  458.             }
  459.             MissileAttack();    /* Shoot the missile */
  460.         }        
  461.     }
  462.  
  463. /* frame 3: second shot for chaingun and flamethrower */
  464.  
  465.     if (gamestate.attackframe == 3) {
  466.         if (gamestate.weapon == WP_CHAINGUN ) {
  467.             if (!gamestate.ammo) {
  468.                 ++gamestate.attackframe;
  469.             } else {
  470.                 GunAttack();        /* Shoot! */
  471.             }
  472.         } else if (gamestate.weapon == WP_FLAMETHROWER )  {
  473.             if (!gamestate.gas) {
  474.                 ++gamestate.attackframe;
  475.             } else {
  476.                 FlameAttack();        /* Flame on! */
  477.             }
  478.         }
  479.         return;
  480.     }
  481.  
  482. /* frame 4: possible auto fire */
  483.  
  484.     if (gamestate.attackframe == 4) {
  485.         if (buttonstate[bt_attack]) {    /* Held down? */
  486.             if ( (gamestate.weapon == WP_MACHINEGUN 
  487.             || gamestate.weapon == WP_CHAINGUN) && gamestate.ammo) {
  488.                 gamestate.attackframe = 2;    /* Fire again */
  489.                 GunAttack();                /* Shoot */
  490.             }
  491.             if (gamestate.weapon == WP_FLAMETHROWER && gamestate.gas) {
  492.                 gamestate.attackframe=2;
  493.                 FlameAttack();        /* Flame again */
  494.             }
  495.         }
  496.         return;
  497.     }
  498.  
  499.     if (gamestate.attackframe == 5) {        /* End the attack */
  500.         switch (gamestate.weapon) {
  501.         case WP_CHAINGUN:
  502.         case WP_MACHINEGUN:
  503.         case WP_PISTOL:
  504.             if (!gamestate.ammo) {
  505.                 OutOfAmmo();        /* Switch weapons */
  506.             } else if (gamestate.weapon == WP_PISTOL && buttonstate[bt_attack]
  507.             && !attackheld) {
  508.                 attackheld = TRUE;
  509.                 gamestate.attackframe = 1;    /* Fire again the pistol */
  510.                 return;
  511.             }
  512.             break;
  513.         case WP_FLAMETHROWER:
  514.             if (!gamestate.gas) {        /* Out of gas? */
  515.                 OutOfAmmo();        /* Change weapons */
  516.             }
  517.             break;
  518.         case WP_MISSILE:
  519.             if (!gamestate.missiles) {    /* Out of missiles? */
  520.                 OutOfAmmo();        /* Switch weapons */
  521.             }
  522.         }        
  523.         gamestate.attackcount = 0;        /* Shut down the attack */
  524.         gamestate.attackframe = 0;
  525.     }
  526. }
  527.  
  528.  
  529.